package kgame5.pbe.atlantic.fsm {
	import kgame5.k3d.core.obj3d.spacial.SpacialVO;
	import kgame5.kutil.SafeTimer;
	import kgame5.pbe.atlantic.event.FSMEvent;
	import kgame5.pbe.atlantic.vo.EntityVO;

	/**
	 * @author kangkai
	 * TODO 这个通过fsm发送event到GameActor.理由是减少GameActor暴露的接口
	 * TODO 注意,以后SpacialManager
	 * 
	 * //正确的用法是这样，这样就可以用Ctril+shift+G来搜索从哪里跳转到的这个状态，并且减少fsm构造时的代码量
	 * public function FallingAndStopStateV2(){
			super(Enum.STATE_FALLING);
		}
	 * 
	 */
	public class GState {
		public static const STATE_EMPTY : int = -1;//状态机的空白状态
		//______________Property____________________
		private var ID : String = "0";//stateID

		protected var timer : SafeTimer = new SafeTimer();//安全的计时器，非常常用

		private var fsm : FSM;// 对外发出事件，切换状态用

		protected var entVO : EntityVO;
		protected var spcVO : SpacialVO;//刚体数据
		
		//很实用的功能，经常需要有状态需要指明自己下一个状态
		public var _followingStateParams:FollowingStateParams;
		
		//一个步骤动作需要执行的各个阶段
		protected var phase:int=-1;
		
		//________________Method____________________

		public function GState(id : String) {
			//其实stateID都是唯一的和一个State的子类对应，所以stateID是在State类声明的时候就自带的， 可以不靠外界传入
			this.ID = id;
		}
		
		public function setFSM(fsm:FSM):void{
			this.fsm = fsm;
		}
		
		public function setEntityVO(vo:EntityVO):void{
			this.entVO=vo;
			
			this.spcVO = entVO.spcVO;
		
			
		}

		public function getID() : String {
			return ID;
		}

		//进入状态,info很重要，在进入一个状态的时候被传入的参数，比如如果是进入移动状态，则要传入移动目的地
		public function enter(info : Object = null) : void {
			
		}

		//执行状态
		public function update() : void {
		}

		//退出状态
		public function exit() : void {
		}
		
		//-------------------实用函数-------------------
		//---被视图通知有事件---
		//由viewComp通知有被点击了
		public function onClick(x:int,y:int):void{
			
		}
		
		//由viewComp通知当前活动的状态时动画播放完毕
		public function onEndOfFrame(animName:String):void{
			
		}
		
		public function onRollOver():void{
			
		}
		
		public function onRollOut():void{
			
		}
		
		
		//----播放动画播放指定动画
		protected function view_playAnim(animID:String):void{
			fsm.sendFSMEvent(FSMEvent.NAME_PLAY_ANIM,animID);
			
		}
		//命令动画切换方向
		protected function view_changeDir(dir:int):void{
			fsm.sendFSMEvent(FSMEvent.NAME_CHANGE_DIR,dir);
		}
		
		//这个是必要的，因为state需要向controller发送事件
		protected function sendFSMEvent(name:String,data:Object=null):void{
			fsm.sendFSMEvent(name,data);
		}
		
		//----切换状态
		//跳转到后继状态
		protected  function gotoFollowingState():void{
			fsm.SwitchState(_followingStateParams.stateID,_followingStateParams.data);
		}
		
		//如果fsmID是null,则表示要切换的状态机是当前的
		//切换指定fsm的状态
		protected function switchState(fsmID:String,stateID:String,data:Object=null,f:FollowingStateParams=null):void{
			if(fsmID==null){
				fsmID=fsm.getID();
			}
			
			fsm.getMaster().SwitchFSMState(fsmID, stateID,data,f);
			
					
		}
		
		//删除自己, 快捷方式
		protected function hack_destroySelfEntity():void{
			fsm.hack_destroySelfEntity();
		}
		
		//--对外传送命令
		//包装一下，为了方便子类调用而已
		protected function sendFromEntityCommand(commandName:String,data:Object=null):void{
			fsm.sendFromEntityCommand(commandName,data);
		}
		
		protected function sendEntityToEntityMessage(msgName : String,toID : String,scope : int=1,data : *=null) : void {
			fsm.sendEntityToEntityMessage(msgName,toID,scope,data);
		}
		//取得某fsm的当前状态,很实用的函数，用于并行状态机间共享消息
//		protected function getFSMCurrStateID(fsmID:String):String{
//			return fsm.getMaster().getFSMStateID(fsmID);
//		}
		
		//很实用的函数，判断某状态机是否处于某状态
		//这个用来解决状态机之间的协作用
		protected function isCurrState(testFsmID:String,testStateID:String):Boolean{
			var currStateID:String=fsm.getMaster().getFSMCurrStateID(testFsmID);
			return currStateID==testStateID;
		}
	}//end of class
}

	//protected var senceWorld:ISenceWorld;
	
	//需要写复杂的程序由GameWorld传入
	//protected var spacialManager:SpacialManager;//空间管理器，寻路径等使用
//	//当Entity被添加到世界后，被world调用，传入
//	public function setSenceWorld(senceWorld:ISenceWorld):void{
//		this.senceWorld=senceWorld;
//	}
//	//当Entity被添加到世界后，被world调用，传入
//	public function setSpacialManager(spacialManager:SpacialManager):void{
//		this.spacialManager=spacialManager;
//	}

//	public function setVO(p_vo:EntityVO):void{
//		this._vo=p_vo;
//	}
//	
//	public function setHardVO(hardVO:HardVO):void{
//		this.hardVO=hardVO;
//		
//		v= hardVO.v3d_v;
//		p= hardVO.v3d_p;
//		r= hardVO.v3d_r;
//	}